
#ifndef __linux_alsa_h__
#define __linux_alsa_h__

#include <stdint.h>
#include "../ijksdl_audio.h"
#include "../ijksdl_aout.h"

typedef struct SDL_Linux_Alsa_Spec {
    enum StreamType {
        STREAM_VOICE_CALL = 0,
        STREAM_SYSTEM = 1,
        STREAM_RING = 2,
        STREAM_MUSIC = 3,
        STREAM_ALARM = 4,
        STREAM_NOTIFICATION = 5,
    } stream_type;

    int sample_rate_in_hz;

    enum ChannelConfig {
        CHANNEL_OUT_INVALID = 0x0,
        CHANNEL_OUT_DEFAULT = 0x1, /* f-l */
        CHANNEL_OUT_MONO = 0x4, /* f-l, f-r */
        CHANNEL_OUT_STEREO = 0xc, /* f-l, f-r, b-l, b-r */
        CHANNEL_OUT_QUAD = 0xcc, /* f-l, f-r, b-l, b-r */
        CHANNEL_OUT_SURROUND = 0x41c, /* f-l, f-r, f-c, b-c */
        CHANNEL_OUT_5POINT1 = 0xfc, /* f-l, f-r, b-l, b-r, f-c, low */
        CHANNEL_OUT_7POINT1 = 0x3fc, /* f-l, f-r, b-l, b-r, f-c, low, f-lc, f-rc */

        CHANNEL_OUT_FRONT_LEFT = 0x4,
        CHANNEL_OUT_FRONT_RIGHT = 0x8,
        CHANNEL_OUT_BACK_LEFT = 0x40,
        CHANNEL_OUT_BACK_RIGHT = 0x80,
        CHANNEL_OUT_FRONT_CENTER = 0x10,
        CHANNEL_OUT_LOW_FREQUENCY = 0x20,
        CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x100,
        CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x200,
        CHANNEL_OUT_BACK_CENTER = 0x400,
    } channel_config;

    enum AudioFormat {
        ENCODING_INVALID = 0,
        ENCODING_DEFAULT = 1,
        ENCODING_PCM_16BIT = 2, // signed, guaranteed to be supported by devices.
        ENCODING_PCM_8BIT = 3, // unsigned, not guaranteed to be supported by devices.
    } audio_format;
    int buffer_size_in_bytes;

    enum Mode {
        MODE_STATIC = 0,
        MODE_STREAM = 1,
    } mode;

    // extra field
    int sdl_samples;
} SDL_Linux_Alsa_Spec;

typedef struct SDL_Linux_Alsa SDL_Linux_Alsa;

SDL_Linux_Alsa *SDL_Linux_Alsa_new_from_spec(SDL_Linux_Alsa_Spec *spec);
SDL_Linux_Alsa *SDL_Linux_Alsa_new_from_sdl_spec(const SDL_AudioSpec *spec);
void SDL_Linux_Alsa_free(SDL_Linux_Alsa* atrack);

int SDL_Linux_Alsa_get_min_buffer_size(SDL_Linux_Alsa *alsa);
void SDL_Linux_Alsa_get_target_spec(SDL_Linux_Alsa *alsa, SDL_AudioSpec *spec);

void SDL_Linux_Alsa_play(SDL_Linux_Alsa *alsa);
void SDL_Linux_Alsa_pause(SDL_Linux_Alsa *alsa);
void SDL_Linux_Alsa_flush(SDL_Linux_Alsa *alsa);
int  SDL_Linux_Alsa_write_byte(SDL_Linux_Alsa *alsa, uint8_t *data, int len);

#endif
